package io.webfolder.cdp;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;

import io.webfolder.cdp.exception.CdpException;

public class LinuxProcessManager extends ProcessManager {

	private int pid;

	private String cdp4jId;

	private CdpProcess process;

	public void setProcess(CdpProcess process) {
		if (this.process != null)
			throw new IllegalStateException();
		try {
			Field pidField = process.getProcess().getClass().getDeclaredField("pid");
			pidField.setAccessible(true);
			this.pid = ((Integer) pidField.get(process.getProcess())).intValue();
			this.process = process;
		} catch (Throwable e) {
			throw new CdpException(e);
		}
		this.cdp4jId = process.getCdp4jProcessId();
	}

	public boolean kill() {
		if (this.process == null)
			return false;
		ProcessBuilder builder = new ProcessBuilder(new String[] { "strings", "-a", "/proc/" + this.pid + "/cmdline" });
		try {
			Process process = builder.start();
			String stdout = toString(process.getInputStream());
			if (!stdout.contains("cdp4jId=" + this.cdp4jId))
				return false;
		} catch (Throwable e) {
			return false;
		}
		try {
			Class<?> clazz = Class.forName("java.lang.UNIXProcess");
			Method destroyProcess = clazz.getDeclaredMethod("destroyProcess", new Class[] { int.class, boolean.class });
			destroyProcess.setAccessible(true);
			boolean force = false;
			destroyProcess.invoke((Object) null, new Object[] { Integer.valueOf(this.pid), Boolean.valueOf(force) });
			return true;
		} catch (Throwable e) {
			return false;
		}
	}

	protected String toString(InputStream is) {
		Scanner scanner = new Scanner(is);
		try {
			scanner.useDelimiter("\\A");
			String str = scanner.hasNext() ? scanner.next() : "";
			scanner.close();
			return str;
		} catch (Throwable throwable) {
			try {
				scanner.close();
			} catch (Throwable throwable1) {
				throwable.addSuppressed(throwable1);
			}
			throw throwable;
		}
	}
}
